#include "./BSP/MPU6050/MPU6050_I2C.h"

//I2C写SCL引脚
void MPU6050_W_SCL(uint8_t Bitvalue)
{
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, (GPIO_PinState)(Bitvalue));
}
//I2C写SDA引脚
void MPU6050_W_SDA(uint8_t Bitvalue)
{
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, (GPIO_PinState)(Bitvalue));
}
//I2C读SDA引脚
uint8_t MPU6050_R_SDA(void)
{
	uint8_t Bitvalue;
	Bitvalue = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_11);
	return Bitvalue;
}

void MPU6050_IIC_IO_Init(void)
{
	GPIO_InitTypeDef gpio_init_struct;

	__HAL_RCC_GPIOB_CLK_ENABLE(); //使能GPIOB时钟

	gpio_init_struct.Pin = GPIO_PIN_10 | GPIO_PIN_11; //PB10 PB11
	gpio_init_struct.Mode = GPIO_MODE_OUTPUT_OD; //开漏输出
	gpio_init_struct.Pull = GPIO_NOPULL; //不拉
	gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; //高速

	HAL_GPIO_Init(GPIOB, &gpio_init_struct); //初始化GPIOB的10和11引脚

	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10 | GPIO_PIN_11, GPIO_PIN_SET); //设置PB10和PB11为高电平
}

//产生MPU6050_IIC起始信号
void MPU6050_IIC_Start(void)
{
	MPU6050_W_SDA(1);
	MPU6050_W_SCL(1);
	delay_us(4);
	MPU6050_W_SDA(0);
	delay_us(4);
	MPU6050_W_SCL(0);
}	  

//产生MPU6050_IIC停止信号
void MPU6050_IIC_Stop(void)
{
	MPU6050_W_SCL(0);
	MPU6050_W_SDA(0);
	delay_us(4);
	MPU6050_W_SCL(1);
	delay_us(4);
	MPU6050_W_SDA(1);
	delay_us(4);
}
//等待应答信号到来
//返回值：1，接收应答失败
//        0，接收应答成功
//接收一个字节
uint8_t MPU6050_IIC_Read_Ack(void)
{
	uint8_t ucErrTime=0;
	MPU6050_W_SDA(1);
	delay_us(4);
	MPU6050_W_SCL(1);
	delay_us(4);
	while (MPU6050_R_SDA())
	{
		ucErrTime++;
		if (ucErrTime>250)
		{
			MPU6050_IIC_Stop();
			return 1;
			/* code */
		}
		/* code */
	}
	MPU6050_W_SCL(0);
	return 0;
}
//发送应答
void MPU6050_IIC_Send_Ack(uint8_t ack)
{
	MPU6050_W_SCL(0);
	MPU6050_W_SDA(ack);
	delay_us(4);
	MPU6050_W_SCL(1);
	delay_us(4);
	MPU6050_W_SCL(0);
}

//MPU6050_IIC发送一个字节
//返回从机有无应答
//1，有应答
//0，无应答		
void MPU6050_IIC_Send_Byte(uint8_t txd)
{
	uint8_t t;
	MPU6050_W_SCL(0);
	for ( t = 0; t < 8; t++)
	{
		if ((txd&0x80)>>7)
			MPU6050_W_SDA(1);
		else
			MPU6050_W_SDA(0);
		txd<<=1;
		delay_us(4);
		MPU6050_W_SCL(1);
		delay_us(4);
		MPU6050_W_SCL(0);
		delay_us(4);
		/* code */
	}
	MPU6050_IIC_Read_Ack();
}
//读一个字节，ack=1时，发送Ack,ack=0,发送nAck
uint8_t MPU6050_IIC_Read_Byte(uint8_t ack)
{
	unsigned char i,receive=0;
	for ( i = 0; i < 8; i++)
	{
		MPU6050_W_SCL(0);
		delay_us(4);
		MPU6050_W_SCL(1);
		receive<<=1;
		if (MPU6050_R_SDA()) receive++;
		delay_us(4);
		/* code */
	}
	MPU6050_W_SCL(0);
	delay_us(4);
	MPU6050_IIC_Send_Ack(ack);
	return receive;
}
//-------------------------------------------------------------------------------------------------------
